package basic.com.liz.mongo.service;

import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.mongodb.BasicDBList;
import com.mongodb.CommandResult;

/**
 * mongodb抽象类
 * 
 * @author 陆小凤
 * @date 2013-8-8
 * 
 * @param <T>
 */
public abstract class AbstractMongodbDao
{
    @Autowired
    private MongoTemplate mongoTemplate;
    
    /**
     * 通过条件查询实体
     * 
     * @param query
     * @param collectionName
     * @return
     */
    public <T> List<T> find(Query query, Class<T> classOfT, String collectionName)
    {
        return mongoTemplate.find(query, classOfT, collectionName);
    }
    
    /**
     * 在指定集合中查询某个实体类的所有记录
     * 
     * @param collectionName
     * @return
     */
    public <T> List<T> findAll(Class<T> classOfT, String collectionName)
    {
        return mongoTemplate.findAll(classOfT, collectionName);
    }
    
    /**
     * 根据条件在指定集合中查询出一条数据
     * 
     * @param query
     * @param collectionName
     * @return
     */
    public <T> T findOne(Query query, Class<T> classOfT, String collectionName)
    {
        return (T)mongoTemplate.findOne(query, classOfT, collectionName);
    }
    
    /**
     * 返回在指定集合中跟ID相同的文档
     * 
     * @param id
     * @param collectionName
     * @return
     */
    public <T> T findById(Object id, Class<T> classOfT, String collectionName)
    {
        return (T)mongoTemplate.findById(id, classOfT, collectionName);
    }
    
    /**
     * 返回在指定集合中符合查询条件的文档个数
     * 
     * @param query
     * @param collectionName
     * @return
     */
    public long getCount(Query query, String collectionName)
    {
        return mongoTemplate.count(query, collectionName);
    }
    
    /**
     * 删除指定的集合
     * 
     * @param collectionName
     */
    public void dropCollection(String collectionName)
    {
        mongoTemplate.dropCollection(collectionName);
    }
    
    /**
     * 更新在指定集合中找到的第一条数据
     * 
     * @param query
     * @param update
     * @param collectionName
     */
    public void updateFirst(Query query, Update update, String collectionName)
    {
        mongoTemplate.updateFirst(query, update, collectionName);
    }
    
    /**
     * 更新在指定集合中找到的所有对象
     * 
     * @param query
     * @param update
     * @param collectionName
     */
    public void updateMulti(Query query, Update update, String collectionName)
    {
        mongoTemplate.updateMulti(query, update, collectionName);
    }
    
    /**
     * 执行更新插入 如果没有发现符合查询条件的文档，则用查询条件和更新内容创建一个新文档，插入
     * 
     * @param query
     * @param update
     * @param collectionName
     */
    public void upsert(Query query, Update update, String collectionName)
    {
        mongoTemplate.upsert(query, update, collectionName);
    }
    
    /**
     * 在指定集合中删除对象
     * 
     * @param object
     * @param collection
     */
    public <T> void remove(T object, String collection)
    {
        mongoTemplate.remove(object, collection);
    }
    
    /**
     * 删除指定集合中所有符合查询条件的文档
     * 
     * @param query
     * @param collectionName
     */
    public void remove(Query query, String collectionName)
    {
        mongoTemplate.remove(query, collectionName);
    }
    
    /**
     * 在指定集合中批量插入
     * 
     * @param batchToSave
     * @param collectionName
     */
    public <T> void insert(Collection<T> batchToSave, String collectionName)
    {
        mongoTemplate.insert(batchToSave, collectionName);
    }
    
    /**
     * 在指定集合中插入对象
     * 
     * @param objectToSave
     * @param collectionName
     */
    public <T> void insert(T objectToSave, String collectionName)
    {
        mongoTemplate.insert(objectToSave, collectionName);
    }
    
    /**
     * 在指定集合中插入对象,如果存在就覆盖，不存在就新插入
     * 
     * @param objectToSave
     * @param collectionName
     */
    public <T> void save(T objectToSave, String collectionName)
    {
        mongoTemplate.save(objectToSave, collectionName);
    }
    
    /**
     * 根据集合名称删除集合
     * 
     * @param collectionName
     */
    public <T> void drop(String collectionName)
    {
        mongoTemplate.dropCollection(collectionName);
    }
    
    /**
     * 查询集合数
     * 
     * @param collectionName
     */
    public <T> Long count(Query query, String collectionName)
    {
        return mongoTemplate.count(query, collectionName);
    }
    
    /**
     * 根据栏目ID查询，节目集ID去重，获取总数
     * 
     * @param collectionName
     */
    @SuppressWarnings("unchecked")
    public <T> int countByDistinct(Query query, String collectionName, String programSeriesId)
    {
        List<T> list = mongoTemplate.getCollection(collectionName).distinct(programSeriesId, query.getQueryObject());
        return list == null ? 0 : list.size();
    }
    
    /**
     * 根据栏目ID查询，节目集ID去重，获取节目集ID列表
     * 
     * @param collectionName
     * @param catgIds
     */
    public <T> BasicDBList findProgramSeriesIdsByDistinct(String collectionName, List<Long> catgIds,
        Integer publishPlatformId)
    {
        String jsonCommand = "";
        if (publishPlatformId == null)
        {
            jsonCommand =
                "{ 'aggregate' : 'epgCatgSeries' , 'pipeline' : [ { '$match' : { 'catgItemId' : { '$in' : " + catgIds
                    + "}}} , { '$group' : { '_id' : '$programSeriesId'}} ]}";
        }
        else
        {
            // jsonCommand =
            // "{ 'aggregate' : 'epgCatgSeries' , 'pipeline' : [ { '$match' : { 'catgItemId' : { '$in' : "+catgIds+"},'finishPlatformIds' : { '$regex' : ';"+
            // publishPlatformId +";'}}} , { '$group' : { '_id' : '$programSeriesId'}} ]}";
            jsonCommand =
                "{ 'aggregate' : 'epgCatgSeries' , 'pipeline' : [ { '$match' : { 'catgItemId' : { '$in' : "
                    + catgIds
                    + "},'$and':[{'$or':[{'isCdn' : 1 , 'finishPlatformIds' : { '$regex' : ';"
                    + publishPlatformId
                    + ";'}},{ 'isCdn' : 0},{ 'isCdn' : { '$exists' : false}}]}]}} , { '$group' : { '_id' : '$programSeriesId'}} ]}";
        }
        
        CommandResult result = mongoTemplate.executeCommand(jsonCommand);
        BasicDBList basicList = (BasicDBList)result.get("result");
        return basicList;
    }
    
    /**
     * 分组查询
     * 
     * @param <T>
     * @param groupBy
     * @param collectionName
     * @param classOfT
     * @return
     */
    public <T> GroupByResults<T> groupSearch(GroupBy groupBy, String collectionName, Class<T> classOfT)
    {
        return mongoTemplate.group(collectionName, groupBy, classOfT);
    }
}
